import 'dart:async';

import 'package:hc_connectivity/wifi_network.dart';

import 'hc_connectivity_platform_interface.dart';
import 'hc_method_channel_connectivity.dart';

/// Discover network HcConnectivity configurations: Distinguish between WI-FI and cellular, check WI-FI status and more.
class HcConnectivity {
  /// Constructs a singleton instance of [HcConnectivity].
  ///
  /// [HcConnectivity] is designed to work as a singleton.
  // When a second instance is created, the first instance will not be able to listen to the
  // EventChannel because it is overridden. Forcing the class to be a singleton class can prevent
  // misuse of creating a second instance from a programmer.
  factory HcConnectivity() {
    if (_singleton == null) {
      _singleton = HcConnectivity._();
    }
    return _singleton!;
  }

  HcConnectivity._();

  static HcConnectivity? _singleton;

  static HcConnectivityPlatform get _platform =>
      HcConnectivityPlatform.instance;

  /// Fires whenever the HcConnectivity state changes.
  Stream<List<WifiNetwork>> get onConnectivityChanged {
    return _platform.onConnectivityChanged;
  }

  /// Checks the connection status of the device.
  ///
  /// Do not use the result of this function to decide whether you can reliably
  /// make a network request. It only gives you the radio status.
  ///
  /// Instead listen for HcConnectivity changes via [onHcConnectivityChanged] stream.
  Future<List<WifiNetwork>> checkConnectivity() {
    return _platform.checkConnectivity();
  }

  /// Obtains the wifi name (SSID) of the connected network
  ///
  /// Please note that it DOESN'T WORK on emulators (returns null).
  ///
  /// From android 8.0 onwards the GPS must be ON (high accuracy)
  /// in order to be able to obtain the SSID.
  Future<String?> getWifiName() {
    return _platform.getWifiName();
  }

  /// Obtains the wifi BSSID of the connected network.
  ///
  /// Please note that it DOESN'T WORK on emulators (returns null).
  ///
  /// From Android 8.0 onwards the GPS must be ON (high accuracy)
  /// in order to be able to obtain the BSSID.
  Future<String?> getWifiBSSID() {
    return _platform.getWifiBSSID();
  }

  /// Obtains the IP address of the connected wifi network
  Future<String?> getWifiIP() {
    return _platform.getWifiIP();
  }

  Future<bool> isEnabled() {
    return _platform.isEnabled();
  }

  setEnabled(bool state) {
    _platform.setEnabled(state);
  }

  Future<bool> isConnected() {
    return _platform.isConnected();
  }

  Future<bool> disconnect() {
    return _platform.disconnect();
  }

  Future<bool> connect(String ssid,
      {String? password,
      NetworkSecurity security = NetworkSecurity.NONE,
      bool joinOnce = true,
      bool withInternet = false}) {
    return _platform.connect(ssid,
        password: password,
        security: security,
        joinOnce: joinOnce,
        withInternet: withInternet);
  }

  Future<bool> forceWifiUsage(bool useWifi) {
    return _platform.forceWifiUsage(useWifi);
  }

  Future<bool> registerWifiNetwork(String ssid,
      {String? password, NetworkSecurity security = NetworkSecurity.NONE}) {
    return _platform.registerWifiNetwork(ssid,
        password: password, security: security);
  }

  Future<bool> removeWifiNetwork(String ssid) {
    return _platform.removeWifiNetwork(ssid);
  }

  ///返回ssid
  Future<String?> openWifiNetwork() {
    return _platform.openWifiNetwork();
  }
}
